﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Utility3D;
using Utility3D.Extensions;
using System.Linq;

namespace Modeller
{
    /// <summary>
    /// Interaction logic for CanvasWrapper.xaml
    /// </summary>
    public partial class CanvasWrapper
    {
        private DrawingSurface _glidedSurface;

        public CanvasWrapper()
        {
            InitializeComponent();
        }

        private Action<CanvasWrapper> _closeAction;
        public Action<CanvasWrapper> CloseAction
        {
            get { return _closeAction; }
            set
            {
                if (value != null) CloseButton.Visibility = Visibility.Visible;
                _closeAction = value;
            }
        }

        private void CloseButtonClick(object sender, RoutedEventArgs e)
        {
            if (CloseAction != null)
                CloseAction(this);
        }

        public void UserControlLoaded(object sender, RoutedEventArgs e)
        {
            if (Canvas.DrawingSurface == null) return;

            var contextMenuItems = Canvas
                .DrawingSurface
                .WorldModel
                .DrawingSurfaceChains;

            ContextMenu.Items.Clear();

            foreach (var contextMenuItem in contextMenuItems)
            {
                var menuItem = new MenuItem {Header = contextMenuItem.Name, Tag = contextMenuItem};
                menuItem.Click += MenuItemClick;
                ContextMenu.Items.Add(menuItem);
            }

            ViewName.Content = Canvas.DrawingSurface.Name;

            DepthSlider.Value = 50;
        }

        private void MenuItemClick(object sender, RoutedEventArgs e)
        {
            var drawingSurface = (DrawingSurface)((MenuItem) sender).Tag;
            ViewName.Content = drawingSurface.Name;
            Canvas.DrawingSurface = drawingSurface;

            DepthSliderValueChanged(sender, null);
        }

        private void DepthSliderValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            var onlyUseDefinedPlanes = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift);

            if (_glidedSurface != null && _glidedSurface.Transient)
                _glidedSurface.DiscardSurface();

            var firstSurface = Canvas.DrawingSurface.ChainWithSelf(ds => ds.PrevSurface).Last();
            if (!onlyUseDefinedPlanes)
            {
                _glidedSurface = firstSurface
                                     .ChainWithSelf(ds => ds.NextSurface)
                                     .FirstOrDefault(ds => ds.DistanceFromBaseSurface == DepthSlider.Value)
                                 ?? firstSurface.Glide(DepthSlider.Value);
            }
            else
            {
                _glidedSurface = firstSurface
                    .ChainWithSelf(ds => ds.NextSurface)
                    .OrderBy(ds => Math.Abs(ds.DistanceFromBaseSurface - DepthSlider.Value))
                    .First();
                DepthSlider.Value = _glidedSurface.DistanceFromBaseSurface;
            }
            Canvas.DrawingSurface = _glidedSurface;
        }
    }
}
